<template>
  <v-form
    ref="formComponent"
    v-model="valid"
    class="pa-1"
    :lazy-validation="options.lazyValidation"
    :class="options.class"
  >
    <v-row no-gutters>
      <template v-for="item in items">
        <v-col
          v-if="dynamicShow(item)"
          :key="item.id"
          class="formLayoutLR"
          cols="12"
          :xs="12"
          :sm="item.constCol || item.smCol || item.cols || 4"
          :md="item.constCol || item.mdCol || item.cols || 4"
          :lg="dynamic_LG_Span(item)"
          :xl="item.constCol || item.xlCol || item.cols || 2"
        >
          <!-- :xl="item.constCol ? item.cols : 2" -->
          <div
            v-if="layout === 'lr'"
            ref="formLabel"
            class="L_R_formLabel pa-1"
            :class="formFlag === 'form' ? 'L_R_FormHeight' : 'L_R_SearchHeight'"
            :style="{ width: (formFlag === 'form' ? item.formWidth : item.searchWidth) + 'px' }"
          >
            <div>
              {{ item.label }}
            </div>
          </div>
          <form-content
            v-model="form[item.prop]"
            class="pa-1 L_R_formContent commonFormItemStyle"
            :class="options.formLayout === 'l&r' ? 'UnshowDefaultLabel' : 'insideFormItemStyle'"
            :hide-detail="options.hideDetail"
            :hide-rules="options.hideRules"
            :form-flag="formFlag"
            :config-item="item"
            @input="$emit('input', form[item.prop])"
          >
          </form-content>
        </v-col>
      </template>
      <template v-if="formFlag === 'searchForm'">
        <operation-component
          :operation-btn-list="options.searchOperation"
          :add-btn-defined="formConfig.searchBtn"
          :add-btn-show="formConfig.searchBtnShow"
          :add-btn-disabled="formConfig.searchBtnDisabled"
          :add-btn-class="formConfig.searchBtnClass"
          @btnListCB="searchBtnCB"
          @tableSearch="tableSearch"
        ></operation-component>
        <!-- :add-btn-show="false" -->
      </template>
    </v-row>
    <form-operation
      v-if="options.operationShow"
      v-model="options.formOperation"
      @formCancel="formCancel"
      @formSave="formSave"
      @buttonListMethodCB="buttonListMethodCB"
      @setFormOperation="val => (options.formOperation = val)"
    >
    </form-operation>
  </v-form>
</template>

<script>
import FormContent from './FormContent.vue'
import FormOperation from './FormOperation.vue'
import { setItemShow, setItemValue } from '@/utils/formCommonUtils'
import { assignObject, isEmptyValue } from '@/utils/tools'
import { descArray } from '@/utils/arraySort'
import { mapGetters } from 'vuex'
import OperationComponent from '../OperationComponent/OperationComponent.vue'

export default {
  // 表单主要组件
  name: 'FormComponent',

  // 引用组件
  components: {
    FormContent,
    FormOperation,
    OperationComponent
  },

  model: {
    prop: 'formConfig',
    event: 'setFormConfig'
  },

  // 父组件传递的props
  props: {
    // 显示表单
    formShow: { type: Boolean, default: true },
    // 表单配置
    formConfig: { type: Object, default: () => ({}) },
    // 表单数据
    formData: { type: Object, default: () => ({}) },
    // 表单类型
    formFlag: { type: String, default: 'form' }
  },

  data() {
    return {
      // 显示重定向
      show: this.formShow,
      // 表格有效值
      valid: true,
      // 搜索项重定位
      items: this.formConfig.itemConfig,
      // 表单
      form: this.formData,
      // 布局类型
      layout: '',
      // 表单类型 参数名
      optionMap: {
        form: 'formOptions',
        searchForm: 'searchOptions'
      },
      // 默认搜索按钮
      searchOperationList: []
    }
  },

  computed: {
    ...mapGetters(['isPC']),

    // 表单配置重定向
    options: {
      get() {
        return this.formConfig[this.optionMap[this.formFlag]]
      },
      set(nv) {
        this.formConfig[this.optionMap[this.formFlag]] = nv
      }
    }
  },

  watch: {
    isPC(nv) {
      this.layout = nv ? 'lr' : 'normal'
      // this.setLayout()
    },

    layout(nv) {
      this.options.layout = nv
      this.setItemStyle()
      this.set_LR_LabelWidth()
    }
  },

  beforeCreate() {
    //
  },

  created() {
    this.setOptions()
    setItemShow(this.show, this.items, 'formShow', true)
    setItemShow(this.show, this.items, 'formWidth', undefined)
    setItemShow(this.show, this.items, 'searchWidth', undefined)
    /** 输入框样式 */
    this.items.forEach(item => {
      setItemValue(item, item.formShow, 'dense', true)
      setItemValue(item, item.formShow, 'outlined', true)
    })
    // setItemShow(this.show, this.items, 'backgroundColor', '#9E9E9E')
    // setItemShow(true, this.items, 'disabled', true)
    this.setLayout()
  },

  mounted() {
    this.setItemStyle()
    this.set_LR_LabelWidth()
  },

  methods: {
    /** 区分 form 与 search form 的配置 start */
    // 设置操作集显隐
    setOptions() {
      if (isEmptyValue(this.formConfig[this.optionMap[this.formFlag]])) {
        this.formConfig[this.optionMap[this.formFlag]] = {}
        this.options = this.formConfig[this.optionMap[this.formFlag]]
        this.options.formOperation = {}
      }

      this.setItemDetails()

      // 普通表单
      if (this.formFlag === 'form') {
        isEmptyValue(this.options.operationShow) ? (this.options.operationShow = true) : this.options.operationShow
      } else {
        // 搜索表单
        this.options.operationShow = false
        // 搜索按钮默认属性
        const defaultProps = {
          title: '查 询',
          method: 'tableSearch',
          icon: 'magnify',
          iconType: 'mdi'
        }
        if (isEmptyValue(this.formConfig.searchBtn)) {
          this.$set(this.formConfig, 'searchBtn', {})
          this.formConfig.searchBtn = defaultProps
        } else {
          this.formConfig.searchBtn = assignObject({ ...defaultProps }, { ...this.formConfig.searchBtn })
        }
        // this.options.searchOperation = this.options.searchOperation.concat(this.searchOperationList)
        // this.options.searchOperation = this.searchOperationList
        // this.searchOperationList = this.searchOperationList.concat(this.options.searchOperation)
        // console.log(this.options)
      }
    },

    // 设置默认表单信息提示
    setItemDetails() {
      if (this.formFlag === 'form') {
        this.options.hideDetail = false
        this.options.hideRules = false
      } else {
        this.options.hideDetail = true
        this.options.hideRules = true
      }
    },

    // 设置布局
    setLayout() {
      this.options.layout = this.isPC ? 'lr' : 'normal'
      this.layout = this.options.layout
    },

    // 设置布局样式
    setItemStyle() {
      if (this.layout === 'lr') {
        this.items.forEach(item => this.$set(item, 'singleLine', true))
      } else {
        this.items.forEach(item => this.$set(item, 'singleLine', false))
      }
    },

    // 动态显隐
    dynamicShow(item) {
      if (this.formFlag === 'form') {
        return isEmptyValue(item.formShow) ? false : item.formShow
      } else {
        return isEmptyValue(item.search) ? false : item.search
      }
    },

    // 动态列宽度
    dynamic_LG_Span(item) {
      if (this.formFlag === 'form') {
        return 'cols' in item ? item.cols : 3
      } else {
        return 'searchCols' in item ? item.searchCols : 3
      }
    },
    /** 区分 form 与 search form 的配置 end */

    /** 公用的默认配置 start*/
    // 左右布局时宽度一致性
    set_LR_LabelWidth(flag) {
      // dialog init 时节点未生成，延迟执行
      setTimeout(() => {
        const labelList = isEmptyValue(this.$refs.formLabel) ? [] : this.$refs.formLabel
        // const labelList = document.getElementsByClassName('L_R_FormHeight')
        // console.log(flag, 'labelList', labelList)
        if (isEmptyValue(labelList)) {
          return
        }
        let widthList = labelList.map(node => node.clientWidth)
        widthList = descArray(widthList)
        // console.log(flag, 'widthList', widthList)
        if (widthList[0] === 0) {
          return
        }
        if (this.formFlag === 'form') {
          this.items.forEach(item => item.type && this.$set(item, 'formWidth', widthList[0]))
        } else {
          this.items.forEach(item => item.type && this.$set(item, 'searchWidth', widthList[0]))
        }
        // console.log(flag, this.items)
      }, 100)
    },
    /** 公用的默认配置 end*/

    copyItems() {},

    /** form operation start*/
    // 取消操作
    formCancel(el) {
      this.$emit('formCancel', el)
    },
    // 保存操作
    formSave(el) {
      this.$emit('formSave', el)
    },

    buttonListMethodCB(methodName, el) {
      // console.log(methodName, el)
      this.$emit('formBtnCB', methodName, el)
    },
    /** form operation end*/

    /** search form operation start */
    searchBtnCB(methodName, i) {
      this[methodName](i)
      // this.$emit('pageBtnCB', methodName, el)
    },

    tableSearch(i) {
      console.log('table search')
    }
    /** search form operation end */
  }
}
</script>

<style lang="scss" scoped>
// 表单左右布局时样式
.formLayoutLR {
  display: flex;
  align-items: center;
  justify-content: center;
}

// 左右布局Label样式
.L_R_formLabel {
  display: flex;
  justify-content: flex-end;
}

// 正常表单的自定义左Label位置
.L_R_FormHeight {
  // height: 40px;
  height: 100%;
  & > div {
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

// 搜索表单的自定义左Label位置
.L_R_SearchHeight {
  align-items: center;
  height: 48px;
}

// 左右布局FormContnet铺满
.L_R_formContent {
  flex: 1;
}

// 通用样式
.commonFormItemStyle {
  & ::v-deep {
    // 去除输入框验证下边距
    .v-input .v-text-field__details {
      margin-bottom: 0px;
    }
  }
}
</style>
